package org.u2ml.app.rest;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response.Status;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import org.u2ml.app.business.ConnectedUserService;
import org.u2ml.app.business.ProjectDiagramService;
import org.u2ml.app.business.ProjectService;
import org.u2ml.app.domain.Project;
import org.u2ml.app.domain.ProjectDiagram;
import org.u2ml.app.domain.RESTResponse;
import org.u2ml.stack.web.WaitingClients;

@Component
@Path("/diagrams")
public class ProjectDiagramResource {
	
	@Autowired
	private ProjectDiagramService diagramService;
	@Autowired
	private ProjectService projectService;
	@Autowired
	private ConnectedUserService connectedUserService;
	
	@POST
	@Produces(MediaType.TEXT_XML)
	public RESTResponse newProjectDiagram(ProjectDiagram diagram) {
		RESTResponse response = new RESTResponse();
		if (diagram.getName() == null || diagram.getName().isEmpty() ||
			diagram.getType() == null || diagram.getType().isEmpty() || 
			diagram.getProjectId() == null) {
			throw new WebApplicationException(Status.BAD_REQUEST);
		}
		Project project = projectService.find(diagram.getProjectId());
		if (project == null)
			response.setErrorCode("project_not_found");
		else {
			diagram.setAttachedProject(project);
			diagram.setLayout("<diagram><umlclasses/></diagram>");
			response.addData(diagramService.save(diagram));
			/** Push **/
			WaitingClients.wakeUpSessions(connectedUserService.contributorSessions(project));
		}
		return response;
	}

	@GET
	@Produces(MediaType.TEXT_XML)
	public RESTResponse getAll() {
		RESTResponse response = new RESTResponse();
		response.addAllData(diagramService.get());
		return response;
	}

	@GET
	@Produces(MediaType.TEXT_XML)
	@Path("/diagram/{oid}")
	public RESTResponse findByOid(@PathParam("oid") Long oid) {
		RESTResponse response = new RESTResponse();
		if (oid == null) {
			throw new WebApplicationException(Status.BAD_REQUEST);
		}
		ProjectDiagram diagram = diagramService.find(oid);
		if (diagram == null)
			response.setErrorCode("diagram_not_found");
		response.addData(diagram);
		return response;
	}
	
	@GET
	@Produces(MediaType.TEXT_XML)
	@Path("/diagram/project/{oid}")
	public RESTResponse findByProjectOid(@PathParam("oid") Long oid) {
		RESTResponse response = new RESTResponse();
		if (oid == null) {
			throw new WebApplicationException(Status.BAD_REQUEST);
		}
		response.addAllData(diagramService.findByProject(oid));
		return response;
	}
	
	@PUT
	@Path("/diagram")
	@Produces(MediaType.TEXT_XML)
	public RESTResponse setProjectDiagram(ProjectDiagram diagram) {
		RESTResponse response = new RESTResponse();
		ProjectDiagram dia = diagramService.find(diagram.getOid());
		if (dia == null)
			response.setErrorCode("diagram_not_found");
		if (diagram.getName() != null) dia.setName(diagram.getName());
		if (diagram.getType() != null) dia.setType(diagram.getType());
		if (diagram.getProjectId() != null) dia.setProjectId(diagram.getProjectId());
		if (diagram.getAttachedProject() != null) dia.setAttachedProject(diagram.getAttachedProject());
		if (diagram.getLayout() != null) dia.setLayout(diagram.getLayout());
		response.addData(diagramService.update(dia));
		/** Push **/
		WaitingClients.wakeUpSessions(connectedUserService.contributorSessions(dia.getAttachedProject()));
		return response;
	}
	
	@DELETE
	@Produces(MediaType.TEXT_XML)
	@Path("diagram/{oid}")
	public RESTResponse deleteDiagram(@PathParam("oid") Long oid) {
		RESTResponse response = new RESTResponse();
		ProjectDiagram dia = diagramService.find(oid);
		if (dia == null)
			response.setErrorCode("diagram_not_found");
		else {
			/** Push **/
			WaitingClients.wakeUpSessions(connectedUserService.contributorSessions(dia.getAttachedProject()));
			diagramService.delete(dia);
		}
		return response;
	}
}
